package com.jiuling.apis.service.balanceService;

import com.alibaba.fastjson.JSON;
import com.jswzc.dao.mdao.DaoSupport;
import com.jswzc.framework.util.ConfigUtil;
import com.jswzc.framework.util.StringUtil;
import com.jswzc.framework.util.URLConectionUtil;
import com.jswzc.framework.util.weixin.HttpRequestUtil;
import com.jswzc.pay.service.balanceService.BalanceServiceI;
import com.jswzc.pay.service.balanceService.BrandOrderServiceI;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.util.*;

/**
 * Created by qziwm on 2017/6/7.
 */
@Service("brandOrderService")
public class BrandOrderServiceImpl implements BrandOrderServiceI{
    @Resource(name = "daoSupport")
    private DaoSupport dao;


    @Autowired
    private BalanceServiceI balanceService;
    @Override
    public Map<String, Object> addOrder(String json) throws Exception {
        Map<String, Object> resMap=new HashMap<>();
        Map<String,Object> parmMap;
        //解析json
        try{
            parmMap= JSON.parseObject(json,Map.class);
        }catch (Exception e)
        {
            resMap.put("code","1");
            resMap.put("errorCode","1001");
                resMap.put("errorMsg","json格式错误");
            return resMap;
        }
        //处理订单
        try {
            resMap=doOperationOrder(parmMap);
        }catch (Exception e)
        {
            resMap.put("code","1");
            resMap.put("errorCode","1002");
            resMap.put("errorMsg","参数异常错误");
            return resMap;
        }
        return resMap;
    }

    @Override
    public Map<String, Object> getOrder(String code) throws Exception {

        Map<String, Object> resMap=new HashMap<>();
        try {
             resMap=(Map<String, Object>) dao.findForObject("OrderDao.getOrderByCode",code);
            if(resMap!=null)
            {
                resMap.put("code","0");
            }else
            {
                resMap=new HashMap<>();
                resMap.put("code","1");
                resMap.put("errorCode","1009");
                resMap.put("errorMsg","没有这条订单");

            }
        }catch (Exception e)
        {
            resMap=new HashMap<>();
            resMap.put("code","1");
            resMap.put("errorCode","1002");
            resMap.put("errorMsg","参数异常错误");
        }


        return resMap;
    }

    @Override
    public Map<String, Object> finishOrder(String code, String openId) throws Exception {
       Map<String,Object> parm=new HashMap<>();
        parm.put("code",code);
        parm.put("openId",openId);
        //获取订单的信息进行商户余额操作
        Map<String,Object> returnMap=new HashMap<>();
        Map<String,Object> balanceMap= (Map<String, Object>) dao.findForObject("OrderDao.getOrderBalanceInfo",parm);
       if(balanceMap==null)
       {
           parm.put("code","1");
           parm.put("errorCode","1009");
           parm.put("errorMsg","没有这条订单");
           return  parm;
       }
        balanceMap.put("state","0");
        balanceMap.put("source","0");
        returnMap= balanceService.updateMerchantBalance(balanceMap);
        if(!"0".equals(returnMap.get("code")))
        {
            parm.put("code","1");
            parm.put("errorCode",returnMap.get("errorCode"));
            parm.put("errorMsg",returnMap.get("errorMsg"));
            return  parm;
        }

        balanceMap.put("state","1");
        balanceMap.put("source","1");
        returnMap= balanceService.updateMerchantBalance(balanceMap);
        if(!"0".equals(returnMap.get("code")))
        {
            parm.put("code","1");
            parm.put("errorCode",returnMap.get("errorCode"));
            parm.put("errorMsg",returnMap.get("errorMsg"));
            return  parm;
        }
        int resCount= (int) dao.update("OrderDao.updateOrderStateAndOpenId",parm);
        parm.clear();
        if(resCount>0)
        {
            parm.put("code","0");
        }
        else
        {
            parm.put("code","1");
            parm.put("errorCode","1009");
            parm.put("errorMsg","没有这条订单");
        }
        return parm;
    }

    private Map<String,Object> doOperationOrder(Map<String, Object> parmMap) throws Exception {
        Map<String, Object> resMap=new HashMap<>();
        //校验商户授权
        boolean isCheck=checkOAuth(parmMap.get("oauthCode").toString(),parmMap.get("shopCode").toString());
        boolean isSecond=checkSym(parmMap);
        if(isCheck&&isSecond)
        {
            //获取发券方案
            Map<String,Object> merchantStrategy= (Map<String, Object>) dao.findForObject("MerchantDao.getMerchantStrategyByMap",parmMap);
            if(merchantStrategy!=null)
            {
                //保存订单并且返回订单id
                Map<String,Object> orderBack=saveOrder(merchantStrategy,parmMap);
                if("1".equals(orderBack.get("code")))
                {
                    return orderBack;//保存失败直接返回错误
                }
                else
                {
                    String id=orderBack.get("id").toString();
                    String qrCode=getQRCode(id);//获取二维码
                    resMap.put("code","0");
                    resMap.put("QRCode",qrCode);
                    resMap.put("cdKey",id);
                    return resMap;//返回成功
                }
            }
            else {
                resMap.put("code","1");
                resMap.put("errorCode","1004");
                resMap.put("errorMsg","没有这个发券方案");
                return resMap;
            }
        }
        else if(!isCheck)
        {
            resMap.put("code","1");
            resMap.put("errorCode","1003");
            resMap.put("errorMsg","授权码错误");
            return resMap;
        }
        else {
            resMap.put("code","1");
            resMap.put("errorCode","1008");
            resMap.put("errorMsg","重复调用接口");
            return resMap;
        }
    }

    private boolean checkSym(Map<String, Object> parmMap) throws Exception {
        List<String> list= (List<String>) dao.findForList("OrderDao.checkSynchronizedByMap",parmMap);
        return list.size()<=0;
    }

    private String getQRCode(String id) {
        String access_token = getAccessToken();
        String requestUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + access_token;
        JSONObject jsonObject = HttpRequestUtil.httpRequest(requestUrl,
                "POST",
                "{\"expire_seconds\": 2592000,\"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": \"" + id + "\"}}}");
        String back = "";
        if(jsonObject!=null && jsonObject.size()>0){
            String ticket = jsonObject.getString("ticket");
            if(StringUtils.isNotBlank(ticket)){
                back = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket="+ticket;
            }
        }
        return back;
    }

    private Map<String,Object> saveOrder(Map<String, Object> merchantStrategy, Map<String, Object> parmMap) throws Exception {
        Map<String,Object> resMap=new HashMap<>();
        Integer type=0;
        Double couponRate=0.0;
        Double coinRate=0.0;
        Double coupon=0.0;
        Double coin=0.0;
        Double orderTotal=0.0;
            String typeString=merchantStrategy.get("type").toString();
            String couponRateString=merchantStrategy.get("coupon_rate").toString();
            String coinRateString=merchantStrategy.get("coin_rate").toString();
            String orderTotalString=parmMap.get("orderTotal").toString();
            if(StringUtil.isNullOrEmpty(typeString)||!StringUtil.isNumeric(typeString))
            {
                resMap.put("code","1");
                resMap.put("errorCode","1005");
                resMap.put("errorMsg","商户发券配置数据错误");
                return resMap;
            }
            else
            {
                type=Integer.valueOf(typeString);
            }
        if(StringUtil.isNullOrEmpty(couponRateString)||!isDouNumeric(couponRateString))
        {
            resMap.put("code","1");
            resMap.put("errorCode","1005");
            resMap.put("errorMsg","商户发券配置数据错误");
            return resMap;
        }
        else
        {
            couponRate=Double.valueOf(couponRateString);
        }
        if(StringUtil.isNullOrEmpty(coinRateString)||!isDouNumeric(coinRateString))
        {
            resMap.put("code","1");
            resMap.put("errorCode","1005");
            resMap.put("errorMsg","商户发券配置数据错误");
            return resMap;
        }
        else
        {
            coinRate=Double.valueOf(coinRateString);
        }
        if(StringUtil.isNullOrEmpty(orderTotalString)||!isDouNumeric(orderTotalString))
        {
            resMap.put("code","1");
            resMap.put("errorCode","1006");
            resMap.put("errorMsg","订单金额错误");
            return resMap;
        }
        else
        {
            orderTotal=Double.valueOf(orderTotalString);
        }
        if(2==type||0==type)
        {coupon=orderTotal*couponRate;//计算发券额
         coin=coinRate*coupon;//发券发贝根据发券额度计算发贝金额
        }
        if(1==type)//只发贝根据订单号计算发贝金额
        {coin=orderTotal*coinRate;}
        DecimalFormat df = new DecimalFormat("#.00");
        parmMap.put("type",type);
        parmMap.put("coupon",coupon);
        parmMap.put("coin",coin);
        parmMap.put("couponRate",couponRate);
        parmMap.put("coinRate",coinRate);
        parmMap.put("feeRate",merchantStrategy.get("fee_rate"));
        String id= getRndNum();
        parmMap.put("id",id);
       int resCount= (int) dao.save("OrderDao.saveOrder",parmMap);
        if(resCount>0)
        {
            resMap.put("code","0");
            resMap.put("id",id);
        }
        else
        {
            resMap.put("code","1");
            resMap.put("errorCode","1007");
            resMap.put("errorMsg","保存订单失败");
        }
        return  resMap;
    }

    private boolean isDouNumeric(String num) {
        boolean back=false;
        try {
            Double dou=Double.valueOf(num);
            back=true;
        }catch (Exception e)
        {
            back=false;
        }
        return back;
    }

    private boolean checkOAuth(String oauthCode, String shopCode) throws Exception {
        Map<String,String> parm=new HashMap<>();
        parm.put("oauthCode",oauthCode);
        parm.put("shopCode",shopCode);
        List<String> list= (List<String>) dao.findForList("MerchantDao.checkByOauthAndId",parm);
        return list.size()>0;
    }

    public String getRndNum() {
        String rndNum=null;
        Random rand = new Random();
        Date now = new Date();
        long t = now.getTime();
        String timeString=String.valueOf(t* 1000L);
        rndNum =(long)rand.nextInt(100)+timeString.substring(2,timeString.length()-3)+(long)rand.nextInt(1000);
        return rndNum;
    }

    public String getAccessToken() {
        String requestUrl = ConfigUtil.get("jnUrl")+"/wx_getToken.ac";
        Map<String,String> map=new HashMap();
        map.put("time",new Date().getTime()+"");
        String res= URLConectionUtil.httpURLConnectionPostDiy(requestUrl,map);
        //accessToken =res;
        String accessToken= JSON.parseObject(res,String.class);
        return accessToken;
    }
}
